package edu.uwm.cs552;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

import edu.uwm.cs552.util.Pair;

public class PlayersTrack {

	private Map<HexEdge, RailState> track;
	private Map<HexEdge, RailState> proposedTrack;
	
	public PlayersTrack() {
		track = new LinkedHashMap<HexEdge, RailState>();
		proposedTrack = new LinkedHashMap<HexEdge, RailState>();
	}
	
	public RailState addTrack(HexEdge edge) {
		return proposedTrack.put(edge, RailState.PROPOSED);
	}
	
	public Map<HexEdge,RailState> getTrack() {
		return track;
	}
	
	public Map<HexEdge,RailState> getProposedTrack() {
		return proposedTrack;
	}
	
	public Map.Entry<HexEdge, RailState> getNextTrack() {
		if(proposedTrack.isEmpty()) return null;
		Iterator<Entry<HexEdge, RailState>> iterator = proposedTrack.entrySet().iterator();
		return iterator.next();
	}
	
	public void updateTrack() {
		Iterator<Entry<HexEdge, RailState>> iterator = track.entrySet().iterator();

		while(iterator.hasNext()) {
			Map.Entry<HexEdge, RailState> mapEntry = (Map.Entry<HexEdge, RailState>) iterator.next();
			switch(mapEntry.getValue()) {
			case BUILD1: mapEntry.setValue(RailState.BUILT); break;
			case BUILD2: mapEntry.setValue(RailState.BUILD1); break;
			case BUILD3: mapEntry.setValue(RailState.BUILD2); break;
			case BUILD4: mapEntry.setValue(RailState.BUILD3); break;
			case BUILD5: mapEntry.setValue(RailState.BUILD4); break;
			case BUILD6: mapEntry.setValue(RailState.BUILD5); break;
			case BUILD7: mapEntry.setValue(RailState.BUILD6); break;
			case BUILD8: mapEntry.setValue(RailState.BUILD7); break;
			case BUILD9: mapEntry.setValue(RailState.BUILD8); break;
			case BUILD10: mapEntry.setValue(RailState.BUILD9); break;
			}
		}
	}
	
	public boolean buildProposed(Player p) {
		Iterator<Entry<HexEdge, RailState>> iterator = proposedTrack.entrySet().iterator();
		boolean startedBuilding = false;

		while(iterator.hasNext() && !startedBuilding) {
			Map.Entry<HexEdge, RailState> mapEntry = (Map.Entry<HexEdge, RailState>) iterator.next();
			if (p.canBuild(getNextTrack())) {
				track.put(mapEntry.getKey(), RailState.BUILD10);
				startedBuilding = true;
			}
			iterator.remove();
		}
		return startedBuilding;
	}
	
	public double calculateCost(HexBoard board) {
		HexEdge edge = getNextTrack().getKey();//e.getKey();
		Pair<HexCoordinate,HexCoordinate> pair = edge.getHexagons();
		double cost = 0.0;
		
		cost = TrackCost.getInstance().getCost();
		if(board.getTerrain(pair.fst) == Terrain.MOUNTAIN)
			cost += TrackMountainCost.getInstance().getCost();
		if(board.getTerrain(pair.snd) == Terrain.MOUNTAIN)
			cost += TrackMountainCost.getInstance().getCost();
		if(board.getTerrain(pair.fst) == Terrain.SMALL || 
				board.getTerrain(pair.snd) == Terrain.SMALL || 
				board.getTerrain(pair.fst) == Terrain.MEDIUM ||
				board.getTerrain(pair.snd) == Terrain.MEDIUM || 
				board.getBarrier(edge) == Barrier.RIVER)
			cost += TrackRiverCityCost.getInstance().getCost();
		if(board.getBarrier(edge) == Barrier.INLET)
			cost += TrackInletCost.getInstance().getCost();
		
		return cost;
	}
	
	public RailState remove(HexEdge edge) {
		if(edge == null) return null;
		return proposedTrack.remove(edge);
	}
	
	public RailState getRailState(HexEdge edge) {
		if(edge == null) return null;
		return track.get(edge);
	}
}
